﻿using Ldt.DataEngine.DataFlowParse.Model;
using Ldt.DataEngine.RuleAssemble;
using Ldt.InformationUnit.Common;
using LdtDataEngin.ModuleDetail.AnalysisModule.CaseCauseBaseInfoExtr.CaseCause;
using LdtDataEngin.ModuleDetail.BaseModule;
using LdtJudge.DataEngine.CallInterface.ConfiCenter;
using LdtJudge.DataEngine.Common.CommHelp;
using LdtJudge.DataEngine.Common.XmlUtility;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model.DataModel.SysCommon;
using LdtJudge.DataEngine.Model.XMLConfigModel.CauseExtractModel;
using LdtJudge.DataEngine.Model.XMLConfigModel.ElmentModel;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace LdtDataEngin.ModuleDetail.AnalysisModule.CaseCauseBaseInfoExtr
{
    /// <summary>
    /// 案由提取分装类
    /// 输入参数:1.外部应用程序传入过来的案由，案件类型，数据源code，卷宗原文
    /// 输出对象:上下文中的案由列表dataContext.DataLayerAns.CaseCausesList
    /// </summary>
    public class CaseCauseExtract : AssermBase
    {
        public string origitxt;

        public CaseCauseExtract(DataContext dataContext, string moduleName)
        {
            this.dataContext = dataContext;
            this.MoudleName = moduleName;
        }

        /// <summary>
        /// 案由提取方法
        /// </summary>
        /// <returns></returns>
        public List<CaseCauseModel> CaseCauseExt()
        {
            dataContext.InteractiveShow.LogShow("    ----------------------进入案由提取中------------------------");
            List<CaseCauseModel> re = new List<CaseCauseModel>();
            var configModel = dataContext.DataLayerSys.GetConfigModel(MoudleName);
            //案由提取模式配置
            ConfigModel extractConfig = null;
            //案由指向配置
            ConfigModel pointConfig = null;
            if (configModel != null)
            {
                extractConfig = configModel.ConfigDetail.FirstOrDefault(a => a.Code.ToLower() == "causeextract");
                pointConfig = configModel.ConfigDetail.FirstOrDefault(a => a.Code.ToLower() == "causepoint");
            }
             CauseExtractModel causeExtractModel = null;
            if (extractConfig == null)
            {
                dataContext.InteractiveShow.LogShow("案由提取模式配置为空! Code:causeextract");
            }
            if (extractConfig != null && !string.IsNullOrWhiteSpace(extractConfig.ConfigContent))
            {
                dataContext.InteractiveShow.LogShow($"执行模块编号:{extractConfig.Code} 执行code:{extractConfig.ExecuteCode} 文件路径:{extractConfig.FilePath}", LogMessageType.Info);
                causeExtractModel = XmlUtility.DeserializeToObject<CauseExtractModel>(extractConfig.ConfigContent);
            }

            //案件类型Code
            var caseTypeCode = dataContext.DataLayerAns.CaseType;
            //文书类型Code
            var bookTypeCode = dataContext.DataLayerAns.SourceCode;

            if (causeExtractModel != null)
            {
                // 获取案由信息
                try
                {
                    var currentExt = causeExtractModel.CaseTypes.FirstOrDefault(x => x.Code.Split(",").Contains(caseTypeCode.ToLower()));
                    if (currentExt != null)
                    {
                        string extractDesc = string.Empty;
                        var bookTypeInfo = currentExt.BookTypes.FirstOrDefault(x => x.Code.Split(",").Contains(bookTypeCode));
                        CauseExtract extModel;
                        if (bookTypeInfo != null)
                        {
                            extModel = bookTypeInfo.CauseExtract;
                        }
                        else
                        {
                            extModel = currentExt.CauseExtract;
                        }
                        var orgText = dataContext.DataLayerAns.FengXiCanShu.Juanzongneirong;
                        string causeId = dataContext.DataLayerAns.CauseId;
                        if(!string.IsNullOrWhiteSpace(causeId))
                            dataContext.InteractiveShow.LogShow($"通过平台参数传入案由：{causeId}");
                        if (extModel.ExtractMode == "1")
                        {
                            extractDesc = "正则";
                            re = GetCausesByRegex(caseTypeCode, causeId, orgText, extModel.RegexCode);
                        }
                        else if (extModel.ExtractMode == "2")
                        {
                            extractDesc = "机器学习";
                            re = GetCausesByMachineLearnPasse(caseTypeCode, causeId, orgText, extModel.RegexCode);
                        }
                        foreach (var cause in re)
                        {
                            cause.AllParentId = cause.CC_ID;
                        }
                        dataContext.DataLayerAns.ExtractCaseCausesList = re;
                        if (re == null || !re.Any())
                            dataContext.InteractiveShow.LogShow($"通过{extractDesc}未提取到案由信息");
                    }
                }
                catch (Exception ex)
                {
                    dataContext.InteractiveShow.LogShow("CaseCauseExtract:CaseCauseExt 案由提取错误:" + ex.Message, LogMessageType.Error);
                }
            }
            CausePointModel causePointModel = null;
            if (pointConfig != null && !string.IsNullOrWhiteSpace(pointConfig.ConfigContent))
            {
                dataContext.InteractiveShow.LogShow($"执行模块编号:{pointConfig.Code} 执行code:{pointConfig.ExecuteCode} 文件路径:{pointConfig.FilePath}", LogMessageType.Info);
                causePointModel = XmlUtility.DeserializeToObject<CausePointModel>(pointConfig.ConfigContent);
            }
            if (dataContext.DataLayerAns.CaseCausesList == null)
            {
                dataContext.DataLayerAns.CaseCausesList = new List<CaseCauseModel>();
            }
            foreach (var causemodel in re)
            {
                CaseCauseModel replaceCause = null;
                if (causePointModel != null)
                {

                    if (causePointModel.Recrods != null && causePointModel.Recrods.Any())
                    {
                        GetSysCaseCause getSysCaseCause = new GetSysCaseCause();
                        var record = causePointModel.Recrods.FirstOrDefault(x => x.Sourceccid == causemodel.CC_ID);
                        if (record != null)
                        {
                            replaceCause = getSysCaseCause.GetModel(record.Targetccid);
                            causemodel.AllParentId = replaceCause.CC_ID;
                        }
                        else
                        {
                            causemodel.AllParentId = causemodel.CC_ID;
                        }
                    }

                }
                var resultCause = replaceCause == null ? causemodel : replaceCause;
                dataContext.DataLayerAns.CaseCausesList.Add(resultCause);
                if (dataContext.DataLayerAns.CausePointDic == null)
                    dataContext.DataLayerAns.CausePointDic = new Dictionary<string, string>();
                if (!dataContext.DataLayerAns.CausePointDic.ContainsKey(causemodel.CC_ID))
                    dataContext.DataLayerAns.CausePointDic.Add(causemodel.CC_ID, resultCause.CC_ID);
                dataContext.InteractiveShow.LogShow("案由提取结果：" + causemodel.CC_Name);
                dataContext.InteractiveShow.LogShow("案由替换后结果：" + resultCause.CC_Name);
            }
            dataContext.DataLayerAns.ExtractCaseCausesList = re;
            dataContext.InteractiveShow.LogShow("    ----------------------案由提取结束------------------------");
            return re;
        }

        /// <summary>
        /// 通过正则提取案由
        /// </summary>
        /// <param name="caseTypeCode">案件类型编号</param>
        /// <param name="caseCause">传入案由ID</param>
        /// <param name="originalText">原文</param>
        /// <param name="regexCode">正则编号</param>
        /// <returns></returns>
        private List<CaseCauseModel> GetCausesByRegex(string caseTypeCode, string caseCause, string originalText, string regexCode)
        {
            IList<Tuple<string, string>> crimeNameList = new List<Tuple<string, string>>();
            List<CaseCauseModel> reList = new List<CaseCauseModel>();
            GetSysCaseCause dalCause = new GetSysCaseCause();
            string MacthKeyWord = string.Empty;
            List<string> criminals = new List<string> { "a1", "a2", "ja1", "jg2", "jb1" };
            bool isCriminal = criminals.Contains(caseTypeCode);
            // 从数据库中获取刑事类型案件的正则编号
            if (!string.IsNullOrEmpty(regexCode) && !string.IsNullOrWhiteSpace(originalText))
            {
                // 传入原文执行正则获取案由
                var rowList = RuleParseClass.GetParseRegCodeList(regexCode, new List<string> { originalText });
                foreach (string causeName in rowList)
                {
                    // 案由名称处理，确保案由名称有且仅有一个“罪”字，
                    string newCauseName = causeName;
                    if (isCriminal == true)
                        newCauseName = (causeName + "罪").Replace("罪罪", "罪");

                    //对提取过的罪名，不再做二次提取。
                    if (crimeNameList.Any(tup => tup.Item1 == newCauseName))
                        continue;
                    else
                        crimeNameList.Add(new Tuple<string, string>(newCauseName, originalText));
                }
            }
            if(!string.IsNullOrWhiteSpace(caseCause))
            {
                var causeIds = caseCause.Split(",", StringSplitOptions.RemoveEmptyEntries).ToList();
                foreach (string cause in causeIds)
                {
                    crimeNameList.Add(new Tuple<string, string>(cause, "平台传入的案由，不进行案由提取！"));
                }
            }
            // 遍历获取到的案由与原文的tuple
            foreach (Tuple<string, string> causeName in crimeNameList)
            {
                //是否平台传入
                bool isIncoming = false;
                if (causeName.Item2.Contains("平台传入的案由"))
                    isIncoming = true;
                //根据案由名称获取案由数据
                CaseCauseModel cause = null;
                if (isCriminal == true)
                    cause = dalCause.GetCauseByName(causeName.Item1,this.dataContext);
                else
                    cause = dalCause.GetModelByCauseName(causeName.Item1, caseTypeCode);
                if (cause != null)
                {
                    if (cause.CC_NodeType == 2)
                    {
                        if (!reList.Exists(x => x.CC_ID == cause.CC_ID))
                        {
                            cause.MatchOrginalText = causeName.Item2;
                            reList.Add(cause);
                            if (isIncoming)
                                dataContext.InteractiveShow.LogShow($"通过平台传入案由结果：{cause.CC_ID}-{cause.CC_Name}");
                            else
                                dataContext.InteractiveShow.LogShow($"通过正则提取案由结果：{cause.CC_ID}-{cause.CC_Name}");
                        }
                    }
                    else
                    {
                        //获取父级Id
                        var allParentId = cause.AllParentId;
                        if (!string.IsNullOrWhiteSpace(allParentId))
                        {
                            var parentIdList = allParentId.Split(',').Reverse().ToList();

                            foreach (var id in parentIdList)
                            {
                                var currentCause = dalCause.GetCauseById(id.Trim());
                                if (currentCause.CC_NodeType == 2)
                                {
                                    if (!reList.Exists(x => x.CC_ID == cause.CC_ID))
                                    {
                                        currentCause.MatchOrginalText = causeName.Item2;
                                        reList.Add(currentCause);
                                        if (isIncoming)
                                            dataContext.InteractiveShow.LogShow($"通过平台传入案由结果：{currentCause.CC_ID}-{currentCause.CC_Name}");
                                        else
                                            dataContext.InteractiveShow.LogShow($"通过正则提取案由结果：{currentCause.CC_ID}-{currentCause.CC_Name}");
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            // 返回案由实体列表
            return reList;

        }
        /// <summary>
        /// 机器学习用于排除
        /// </summary>
        /// <param name="caseTypeCode">案件类型编号</param>
        /// <param name="caseCause">传入案由Id</param>
        /// <param name="originalText">原文</param>
        /// <param name="modelId">机器学习编号</param>
        /// <returns></returns>
        public List<CaseCauseModel> GetCausesByMachineLearnPasse(string caseTypeCode, string caseCause, string originalText, string modelId = "XZZF_anyuan")
        {
            IList<Tuple<string, string>> crimeNameList = new List<Tuple<string, string>>();
            List<CaseCauseModel> reList = new List<CaseCauseModel>();
            GetSysCaseCause dalCause = new GetSysCaseCause();
            string MacthKeyWord = string.Empty;
            List<string> criminals = new List<string> { "a1", "a2", "ja1", "jg2", "jb1" };
            bool isCriminal = criminals.Contains(caseTypeCode);
            //进行机器学习提取
            reList = GetCausesByMachineLearn(originalText, modelId);
            if(!string.IsNullOrWhiteSpace(caseCause))
            {
                var causeIds = caseCause.Split(",", StringSplitOptions.RemoveEmptyEntries).ToList();
                foreach (string cause in causeIds)
                {
                    crimeNameList.Add(new Tuple<string, string>(cause, "平台传入的案由，不进行案由提取！"));
                }
            }
            // 遍历获取到的案由与原文的tuple
            foreach (Tuple<string, string> causeName in crimeNameList)
            {
                //是否平台传入
                bool isIncoming = false;
                if (causeName.Item2.Contains("平台传入的案由"))
                    isIncoming = true;
                //根据案由名称获取案由数据
                CaseCauseModel cause = null;
                if (isCriminal == true)
                    cause = dalCause.GetCauseByName(causeName.Item1);
                else
                    cause = dalCause.GetModelByCauseName(causeName.Item1, caseTypeCode);
                if (cause != null)
                {
                    if (cause.CC_NodeType == 2)
                    {
                        if(!reList.Exists(x=>x.CC_ID==cause.CC_ID))
                        {
                            cause.MatchOrginalText = causeName.Item2;
                            reList.Add(cause);
                            if (isIncoming)
                                dataContext.InteractiveShow.LogShow($"通过平台传入案由结果：{cause.CC_ID}-{cause.CC_Name}");
                            else
                                dataContext.InteractiveShow.LogShow($"通过机器学习提取案由结果：{cause.CC_ID}-{cause.CC_Name}");
                        }
                    }
                    else
                    {
                        //获取父级Id
                        var allParentId = cause.AllParentId;
                        if (!string.IsNullOrWhiteSpace(allParentId))
                        {
                            var parentIdList = allParentId.Split(',').Reverse().ToList();
                            foreach (var id in parentIdList)
                            {
                                var currentCause = dalCause.GetCauseById(id.Trim());
                                if (currentCause.CC_NodeType == 2)
                                {
                                    if (!reList.Exists(x => x.CC_ID == cause.CC_ID))
                                    {
                                        currentCause.MatchOrginalText = causeName.Item2;
                                        reList.Add(currentCause);
                                        if (isIncoming)
                                            dataContext.InteractiveShow.LogShow($"通过平台传入案由结果：{currentCause.CC_ID}-{currentCause.CC_Name}");
                                        else
                                            dataContext.InteractiveShow.LogShow($"通过机器学习提取案由结果：{currentCause.CC_ID}-{currentCause.CC_Name}");
                                    }
                                    break;
                                }
                            }

                        }
                    }
                }
            }
            // 返回案由实体列表
            return reList;
        }
        /// <summary>
        /// 通过机器学习提取案由
        /// </summary>
        /// <param name="originalText">原文</param>
        /// <returns></returns>
        public List<CaseCauseModel> GetCausesByMachineLearn(string originalText, string modelId = "XZZF_anyuan")
        {
            List<CaseCauseModel> reList = new List<CaseCauseModel>();
            if(!string.IsNullOrWhiteSpace(originalText))
            {
                string recogService = ConfigRetrieval.GetConfigRetrieval.GetAppSettingString("causedistinguish");
                string url = $"{recogService}/CaseCauseValid/CaseCauseValid/GetSingelVerification";
                var recogParam = new
                {
                    content = originalText,
                    modelId = modelId
                };
                string recogCauses = string.Empty;
                string recogReturn = string.Empty;
                //调用案由识别服务
                recogReturn = WebUtil.DoPostNew(url, recogParam);
                dynamic recogResult = null;
                if (!string.IsNullOrWhiteSpace(recogReturn))
                    recogResult = JsonConvert.DeserializeObject<dynamic>(recogReturn);
                if (recogResult != null && recogResult?.code == "1")
                {
                    recogCauses = recogResult.body?.sign;
                }
                if (!string.IsNullOrWhiteSpace(recogCauses))
                {
                    List<string> causeStrs = recogCauses.Split(",").ToList();
                    GetSysCaseCause dalCause = new GetSysCaseCause();
                    foreach (var cause in causeStrs)
                    {
                        var ccid = cause.Split("_")[0];
                        CaseCauseModel caseCause = dalCause.GetCauseById(ccid);
                        if (caseCause != null)
                        {
                            caseCause.MatchOrginalText = originalText;
                            reList.Add(caseCause);
                        }
                    }
                }
            }
            return reList;
        }

    }
}
